import { ToolCall, ToolResult, ToolUsageStatus } from '../types';
import { mcpManager, ToolCallRequest } from './mcpManager';

/**
 * 工具执行状态回调
 */
export type ToolStatusCallback = (status: ToolUsageStatus) => void;

/**
 * 工具调用执行器 - 处理AI模型的工具调用请求
 */
class ToolExecutor {
  private statusListeners: Array<ToolStatusCallback> = [];
  private callCounter = 0;

  /**
   * 添加状态监听器
   */
  addStatusListener(callback: ToolStatusCallback): () => void {
    this.statusListeners.push(callback);
    
    // 返回取消监听函数
    return () => {
      const index = this.statusListeners.indexOf(callback);
      if (index > -1) {
        this.statusListeners.splice(index, 1);
      }
    };
  }

  /**
   * 通知状态变化
   */
  private notifyStatusChange(status: ToolUsageStatus): void {
    this.statusListeners.forEach(callback => {
      try {
        callback(status);
      } catch (error) {
        console.error('工具状态监听器错误:', error);
      }
    });
  }

  /**
   * 解析AI模型的工具调用请求
   */
  parseToolCalls(text: string): ToolCall[] {
    const toolCalls: ToolCall[] = [];
    
    // 简单的工具调用解析（实际应该根据AI模型的输出格式调整）
    const toolCallPattern = /\[TOOL_CALL:(\w+):(\w+):({.*?})\]/g;
    let match;
    
    while ((match = toolCallPattern.exec(text)) !== null) {
      const [, serverId, toolName, parametersStr] = match;
      
      try {
        const parameters = JSON.parse(parametersStr);
        const toolCall: ToolCall = {
          id: `call_${++this.callCounter}`,
          mcpServer: serverId,
          toolName,
          parameters,
          timestamp: new Date(),
          status: 'pending'
        };
        
        toolCalls.push(toolCall);
      } catch (error) {
        console.error('解析工具调用参数失败:', error);
      }
    }
    
    return toolCalls;
  }

  /**
   * 执行工具调用
   */
  async executeToolCall(toolCall: ToolCall): Promise<ToolResult> {
    const startTime = new Date();
    
    // 通知开始执行
    const status: ToolUsageStatus = {
      mcpServerName: toolCall.mcpServer,
      toolName: toolCall.toolName,
      status: 'calling',
      startTime,
      parameters: toolCall.parameters
    };
    this.notifyStatusChange(status);

    try {
      // 构建MCP工具调用请求
      const request: ToolCallRequest = {
        serverId: toolCall.mcpServer,
        toolName: toolCall.toolName,
        parameters: toolCall.parameters
      };

      // 执行工具调用
      const result = await mcpManager.callTool(request);
      const endTime = new Date();
      const duration = endTime.getTime() - startTime.getTime();

      // 更新状态为成功
      const successStatus: ToolUsageStatus = {
        ...status,
        status: 'success',
        duration,
        result
      };
      this.notifyStatusChange(successStatus);

      // 返回结果
      const toolResult: ToolResult = {
        id: `result_${toolCall.id}`,
        toolCallId: toolCall.id,
        result,
        timestamp: endTime
      };

      return toolResult;
    } catch (error) {
      const endTime = new Date();
      const duration = endTime.getTime() - startTime.getTime();

      // 更新状态为失败
      const errorStatus: ToolUsageStatus = {
        ...status,
        status: 'error',
        duration
      };
      this.notifyStatusChange(errorStatus);

      // 返回错误结果
      const toolResult: ToolResult = {
        id: `result_${toolCall.id}`,
        toolCallId: toolCall.id,
        result: null,
        timestamp: endTime,
        error: error instanceof Error ? error.message : '未知错误'
      };

      return toolResult;
    }
  }

  /**
   * 批量执行工具调用
   */
  async executeToolCalls(toolCalls: ToolCall[]): Promise<ToolResult[]> {
    const results: ToolResult[] = [];
    
    // 串行执行工具调用以避免资源竞争
    for (const toolCall of toolCalls) {
      try {
        const result = await this.executeToolCall(toolCall);
        results.push(result);
      } catch (error) {
        console.error(`工具调用 ${toolCall.id} 执行失败:`, error);
        
        // 即使失败也要记录结果
        const errorResult: ToolResult = {
          id: `result_${toolCall.id}`,
          toolCallId: toolCall.id,
          result: null,
          timestamp: new Date(),
          error: error instanceof Error ? error.message : '未知错误'
        };
        results.push(errorResult);
      }
    }
    
    return results;
  }

  /**
   * 格式化工具结果为AI可理解的文本
   */
  formatToolResults(toolResults: ToolResult[]): string {
    if (toolResults.length === 0) {
      return '';
    }

    const formattedResults = toolResults.map(result => {
      if (result.error) {
        return `[TOOL_ERROR:${result.toolCallId}:${result.error}]`;
      } else {
        const resultStr = typeof result.result === 'object' 
          ? JSON.stringify(result.result) 
          : String(result.result);
        return `[TOOL_RESULT:${result.toolCallId}:${resultStr}]`;
      }
    });

    return formattedResults.join('\n');
  }

  /**
   * 检查文本是否包含工具调用
   */
  hasToolCalls(text: string): boolean {
    return /\[TOOL_CALL:\w+:\w+:{.*?}\]/.test(text);
  }

  /**
   * 获取可用工具列表
   */
  getAvailableTools(): Array<{ serverId: string; toolName: string; description?: string }> {
    return mcpManager.getAvailableTools();
  }

  /**
   * 生成工具使用说明
   */
  generateToolUsageInstructions(): string {
    const tools = this.getAvailableTools();
    
    if (tools.length === 0) {
      return '当前没有可用的工具。';
    }

    const instructions = [
      '以下是可用的工具，你可以在回复中使用它们：',
      '',
      '使用格式: [TOOL_CALL:服务器ID:工具名:{"参数":"值"}]',
      '',
      '可用工具：'
    ];

    tools.forEach(tool => {
      instructions.push(`- ${tool.serverId}:${tool.toolName} - ${tool.description || '无描述'}`);
    });

    instructions.push('');
    instructions.push('示例: [TOOL_CALL:File-Operations:read_file:{"path":"./README.md"}]');

    return instructions.join('\n');
  }

  /**
   * 清理资源
   */
  cleanup(): void {
    this.statusListeners.length = 0;
  }
}

// 导出单例
export const toolExecutor = new ToolExecutor();